// typescript 的类型有：字符串、数字(都是浮点数)、结构体、布尔、枚举、数组、元组 Tuple、any类型（任意的）、void(没有任何类型)、null 与  undefined、Never、Object、type




// 数字
var number10: number = 2;
var number2: number = 0b10100011
var number8: number = 0o32
var number16: number = 0xf00d



// 字符串
var str: string = "wwj";
// 字符串--使用模板:被反引号包围（ `）,并且以${ expr }这种形式嵌入表达式。下面的两种方式等同
var strTep: string = `his is ${str}`;
var strTep2: string = "his is" + str;



// 布尔
var boolean: boolean = false;



// 数组--有两种定义方式：
var arr: number[] = [];
arr[0] = 234;   // 赋值 
var arr2: Array<number> = [1, 23, 4, 4, 55, 6, 23, 110];



// 元组 Tuple---表示一个已知元素数量和类型的数组，各元素的类型不必相同
var tuple: [number, string];
tuple = [234, "wwj"];   // 这样和定义元祖是的数量和类型都一样，能正确执行
// tuple = ["wwj", 110];   // 这样赋值时，和定义元祖时的数量一样，但是类型不一一对应，所以保存。
// tuple = [12, "wwj", "wwj2"];    // 和定义元祖时的数量不一样



// 枚举----
// 定义枚举默认情况下，从0开始为元素编号
enum Color {
    RED, GREEN, BLUE
}
// 使用枚举
var enumC: Color = Color.BLUE;
console.log("enumC:", enumC);   // 结果为 2 ， 表示其值在枚举的索引下标数
// 第二种方法：手动的指定成员的数值,可以全部指定，也可以部分指定（其余的后再指定的后面递增）
enum Color2 {
    RED = 2, GREEN, BLUE
}
var enumC2: Color2 = Color2.BLUE
console.log("enumC2:", enumC2);   // 结果为 4
// 知道数值为2,查找相应的名字
var enumStr: string = Color2[2]
console.log("enumStr:", enumStr) // 结果为 RED


// any类型---类型检查器不对这些值进行检查
// 基本类型
var any1: any;
any1 = "wwj";
any1 = 110;
// 数组
var anyArr: any[];
anyArr = [110, "wwj", false, {}]




// void----
// void类型像是与any类型相反，它表示没有任何类型。 例如一个函数没有返回值时，你通常会见到其返回值类型是 void：
// 声明一个void类型的变量没有什么大用，因为你只能为它赋予undefined和null：
var voidPro: void = null
var voidPro2: void = undefined
function warnUser(): void {
    console.log("This is my warning message");
}




// null 与  undefined
// 默认情况下null和undefined是所有类型的子类型
// 指定了--strictNullChecks标记，null和undefined只能赋值给void和它们各自。
var null1: null = null;
var undefined1: undefined = undefined1
number10 = null;    // 所有类型的子类型



// never
// 表示的是那些永不存在的值的类型
// never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型； 变量也可能是 never类型，当它们被永不为真的类型保护所约束时。
// 返回never的函数必须存在无法达到的终点
function while1(): never {
    while (true) { }
}
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
    throw new Error(message);
}
function fail() {
    return error("Something failed");
}




// Object
// object表示非原始类型，也就是除number，string，boolean，symbol，null或undefined之外的类型。
declare function create(o: object | null): void;
create({ prop: 0 }); // OK
create(null); // OK



// 类型断言
// 两种使用方式：其一是“尖括号”语法、另一个为as语法
let strAss: string = " this is string ";
let numberForString: number = (<string>strAss).length
numberForString = (strAss as string).length



// 关于let
// 很多常见的问题都可以通过使用 let来解决，所以尽可能地使用let来代替var吧。




// type
// 先定义类型再使用类型
type C = { a: string, b?: number }
function f1({ a, b }: C): void {
    // ...
}